package activities;

/**
 * JUST A TEST FUNCTION.. 
 */
import helper.LogfileWriter;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.example.intellifit.R;

public class RepetitionsActivityTest extends Activity implements
		SensorEventListener {

	/*
	 * time smoothing constant for low-pass filter 0 ≤ alpha ≤ 1 ; a smaller
	 * value basically means more smoothing See:
	 * http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization
	 */
	static final float ALPHA = 0.15f;

	static final int nrOfEventToMiddle = 5;

	private float[][] middleList = new float[3][nrOfEventToMiddle];
	private int middleListCounter = 0;
	float[] myEventValues = new float[3];

	ArrayList<float[]> allSensorValues = new ArrayList<float[]>();

	int sensor_i = 0;

	/* --DETECTING MOVEMENT: */
	/**
	 * Thresholds defining the "beginning" of a movement as well as the "ending"
	 **/
	private final double THRESHOLD_START_REP = 3;
	private final double THRESHOLD_END_REP = 1;
	private final double THRESHOLD_MIN_MOTION = 0.3;
	/** The value of the accelereometers noise. **/
	private final float NOISE = (float) 1.2;
	/** Timestamp of the last sensor event **/
	private long lastUpdate = 0;

	private float[] lastValues = { 0, 0, 0 };
	private boolean dataAcquiringStarted = false;

	private List<float[]> accValues = new ArrayList<float[]>();
	/* --END DETECTING MOVEMENT */

	/* --LOG WRITING */
	private static final String TAG = "SENSORDATEN";
	public LogfileWriter lfw = new LogfileWriter();
	static final String csvDelimiter = ";";
	/* --END LOG WRITING */

	/* --VIEW COMPONENTS */
	private TextView info;
	private TextView currReps;
	private Button startButton;
	private Button giveUpBtn;
	/* --END VIEW COMPONENTS */

	/* --SENSORS */
	private SensorManager sManager;
	private SensorEventListener thislistener = this;
	/* --END SENSORS */

	/* --END Variables for Sensors and analysis for their data. */

	/* --DATA FOR THE CURRENT EXERCISE */
	private int nrOfReps = 8;
	private int nrOfSets = 3;

	/* --END DATA FOR CURRENT EXERCISE */

	private boolean useTouchEvents = true;
	private int reps = 0;
	private boolean started = false;

	private ArrayList<String> logList = new ArrayList<String>();

	public int getNrOfReps() {
		return nrOfReps;
	}

	public void setNrOfReps(int nrOfReps) {
		this.nrOfReps = nrOfReps;
	}

	public int getNrOfSets() {
		return nrOfSets;
	}

	public void setNrOfSets(int nrOfSets) {
		this.nrOfSets = nrOfSets;
	}

	public void registerListeners() {

		// register our listener
		sManager.registerListener(this,
				sManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
				SensorManager.SENSOR_DELAY_UI);
		// sManager.registerListener(this,
		// sManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
		// SensorManager.SENSOR_DELAY_UI);
	}

	public void unRegisterListeners() {

		// register our listener
		sManager.unregisterListener(this,
				sManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION));
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		started = false;
		super.onCreate(savedInstanceState);
		sManager = (SensorManager) getSystemService(SENSOR_SERVICE);

		setContentView(R.layout.activity_repetition_logfilewriter);

		// init some gui stuff and log
		currReps = (TextView) findViewById(R.id.currRepetition);

		lastUpdate = System.currentTimeMillis();

		giveUpBtn = (Button) findViewById(R.id.giveUpBtn);

		giveUpBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (started) {
					// schreiben
					unRegisterListeners();

					for (String s : logList) {
						lfw.saveToExternalStorage(s, "fdas");
					}
				} else {
					registerListeners();

				}

				started = !started;

				currReps.setText(LogfileWriter.static_nextNumberStr);
			}
		});

	}

	@Override
	protected void onResume() {
		super.onResume();
		registerListeners();
	}

	@Override
	protected void onPause() {
		super.onPause();
		started = false;
		this.sManager.unregisterListener(this);
	}

	protected float[] lowPass(float[] input, float[] output) {
		if (output == null)
			return input;

		for (int i = 0; i < input.length; i++) {
			output[i] = output[i] + ALPHA * (input[i] - output[i]);
		}
		return output;
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		if (started) {
			lfw.setContext(this);

			switch (event.sensor.getType()) {

			case Sensor.TYPE_LINEAR_ACCELERATION:

				String csvLinebla = "";

				csvLinebla += event.values[0] + csvDelimiter + event.values[1]
						+ csvDelimiter + event.values[2] + csvDelimiter;

				csvLinebla = csvLinebla.replace('.', ',');
				logList.add(csvLinebla);

				break;

			}
		}

	}

	public void middleFenster(SensorEvent event) {

	}

	public void middleStatisch(SensorEvent event) {
		middleList[0][middleListCounter] = event.values[0];
		middleList[1][middleListCounter] = event.values[1];
		middleList[2][middleListCounter] = event.values[2];
		middleListCounter++;

		if (middleListCounter == nrOfEventToMiddle) {
			middleListCounter = 0;

			for (int dimension = 0; dimension < 3; dimension++) {
				float sum = 0;
				for (int i = 0; i < nrOfEventToMiddle; i++) {
					sum += middleList[dimension][i];
				}
				myEventValues[dimension] = sum / (float) nrOfEventToMiddle;
			}
			String csvLinebla2 = myEventValues[0] + csvDelimiter
					+ myEventValues[1] + csvDelimiter + myEventValues[2];
			csvLinebla2 = csvLinebla2.replace('.', ',');
			logList.add(csvLinebla2);
		}
	}

	public void logIt() {

	}

	public void handleAccelereometerEvent(SensorEvent event) {

		long currTime = System.currentTimeMillis();
		float[] lin_acc = event.values;

		if (dataAcquiringStarted) {
			this.accValues.add(lin_acc);

		}

		// TODO: evtl prozentuelle Aufteilung auf die jeweilige Achse
		double accelationSquareRoot = Math.sqrt((double) (lin_acc[0]
				* lin_acc[0] + lin_acc[1] * lin_acc[1] + lin_acc[2]
				* lin_acc[2]));

		if (accelationSquareRoot >= THRESHOLD_START_REP
				&& !dataAcquiringStarted) {
			// set flag to acquire data for the current movement.
			dataAcquiringStarted = true;
			this.accValues.add(lin_acc);
			Log.i(TAG, "REP STARTED!");
		}

		if (accelationSquareRoot <= THRESHOLD_END_REP
				&& accelationSquareRoot >= THRESHOLD_MIN_MOTION
				&& dataAcquiringStarted) {
			// process the acquired data to determine if the current
			// movement was a "down" movement
			Log.i(TAG, "REP ENDED!");
			float accelSumYAxis = 0;
			float accelSumZAxis = 0;
			for (int i = 0; i < this.accValues.size(); i++) {
				accelSumYAxis += this.accValues.get(i)[1];
				accelSumZAxis += this.accValues.get(i)[2];
			}
			float accelMeanYAxis = accelSumYAxis / (this.accValues.size());
			float accelMeanZAxis = accelSumZAxis / (this.accValues.size());

			Log.i(TAG, "AccelMeanY: " + accelMeanYAxis);
			Log.i(TAG, "AccelMeanZ: " + accelMeanZAxis);
			if (accelMeanYAxis < THRESHOLD_MIN_MOTION) {
				// for detecting bizep curls
				if (accelMeanZAxis > 0) {
					reps++;

				}
			} else {
				// reps++; updateView();
			}

			dataAcquiringStarted = false;
			this.accValues = new ArrayList<float[]>();
		}
		lastUpdate = currTime;

	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub

	}

}
